package com.bzsg.simpleMediaPlayer.repository

import android.content.ContentUris
import android.content.Context
import android.graphics.Bitmap
import android.media.MediaMetadataRetriever
import android.os.Build
import android.provider.MediaStore
import android.util.LruCache
import android.util.Size
import com.bzsg.simpleMediaPlayer.data.VideoItem
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.util.concurrent.TimeUnit
import javax.inject.Inject

class VideoRepository
    @Inject
    constructor(
        @ApplicationContext private val context: Context,
    ) {
        private val cache = LruCache<Long, Bitmap>(50)

        suspend fun getVideos(): List<VideoItem> =
            withContext(Dispatchers.IO) {
                val videoList = mutableListOf<VideoItem>()
                val projection =
                    arrayOf(
                        MediaStore.Video.Media._ID,
                        MediaStore.Video.Media.DISPLAY_NAME,
                        MediaStore.Video.Media.DATA,
                        MediaStore.Video.Media.DURATION,
                        MediaStore.Video.Media.SIZE,
                    )

                context.contentResolver.query(
                    MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                    projection,
                    null,
                    null,
                    "${MediaStore.Video.Media.DATE_ADDED} DESC",
                )?.use { cursor ->
                    val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID)
                    val nameColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME)
                    val pathColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)
                    val durationColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION)
                    val sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE)

                    while (cursor.moveToNext()) {
                        val id = cursor.getLong(idColumn)
                        val name = cursor.getString(nameColumn)
                        val path = cursor.getString(pathColumn)
                        val duration = cursor.getLong(durationColumn).formatAsTime()
                        val size = cursor.getLong(sizeColumn)
                        videoList.add(VideoItem(id, name, path, duration, size))
                    }
                }
                return@withContext videoList
            }

        // 格式化时间 (ms -> mm:ss)
        private fun Long.formatAsTime(): String {
            val minutes = TimeUnit.MILLISECONDS.toMinutes(this)
            val seconds = TimeUnit.MILLISECONDS.toSeconds(this) % 60
            return String.format("%02d:%02d", minutes, seconds)
        }

        suspend fun generate(
            context: Context,
            mediaId: Long,
        ): Bitmap? =
            withContext(Dispatchers.IO) {
                cache[mediaId] ?: run {
                    try {
                        val collection = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
                        val videoUri = ContentUris.withAppendedId(collection, mediaId)
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                            context.contentResolver.loadThumbnail(videoUri, Size(240, 240), null)
                        } else {
                            // 降级方案：使用MediaMetadataRetriever
                            context.contentResolver.openFileDescriptor(videoUri, "r")?.use { pfd ->
                                MediaMetadataRetriever().run {
                                    setDataSource(pfd.fileDescriptor)
                                    getFrameAtTime(1_000_000)
                                }
                            }
                        }?.also { bitmap ->
                            cache.put(mediaId, bitmap)
                        }
                    } catch (e: Exception) {
                        null
                    }
                }
            }
    }
